@node Shared bindings between Scheme and C
@section Shared bindings between Scheme and C

@cindex sharing data between Scheme and C
@stindex shared-bindings
Shared bindings are the means by which named values are shared between
Scheme & C code.  There are two separate tables of shared bindings, one
for values defined in Scheme and accessed from C and the other for the
opposite direction.  Shared bindings actually bind names to cells, to
allow a name to be resolved before it has been assigned.  This is
necessary because C initialization code may run before or after the
corresponding Scheme code, depending on whether the Scheme code is in
the resumed image or run in the current session.  The Scheme bindings
described here are available from the @code{shared-bindings}
structure.

@subsection Scheme shared binding interface

@deffn {Scheme procedure} shared-binding? object @returns{} boolean
@deffnx {Scheme procedure} shared-binding-is-import? shared-binding @returns{} boolean
@code{Shared-binding?} is the disjoint type predicate for all shared
bindings, imported or exported; @code{shared-binding-is-import?}
returns true if @var{shared-binding} was imported into Scheme from C,
and false if it has the converse direction.
@end deffn

@deffn {Scheme procedure} shared-binding-ref shared-binding @returns{} value
@deffnx {Scheme procedure} shared-binding-set! shared-binding value @returns{} unspecified
@code{Shared-binding-ref} returns the value of @var{shared-binding};
@code{shared-binding-set!} sets the value of @var{shared-binding} to
be @var{value}.
@end deffn

@cindex importing bindings into Scheme from C
@deffn {Scheme procedure} lookup-imported-binding name @returns{} shared-binding
@deffnx {Scheme procedure} define-imported-binding name value @returns{} unspecified
@deffnx {Scheme procedure} undefine-imported-binding name @returns{} unspecified
@code{Lookup-imported-binding} returns the binding imported from C to
Scheme with the given name; a binding is created if none exists.
@code{Define-imported-binding} creates a new such binding, anomalously
from within Scheme; such bindings are usually created instead from
within C using the C @code{s48_define_exported_binding} function.
@code{Undefine-imported-binding} removes the shared binding whose name
is @var{name} from the table of imported bindings.
@end deffn

@cindex exporting bindings from Scheme to C
@deffn {Scheme procedure} lookup-exported-binding name @returns{} shared-binding
@deffnx {Scheme procedure} define-exported-binding name value @returns{} unspecified
@deffnx {Scheme procedure} undefine-exported-binding name @returns{} unspecified
Equivalents of the above three procedures, but for bindings exported
from Scheme to C.  @code{Define-imported-binding}, unlike
@code{define-exported-binding}, is customary to use in Scheme, as its
intended use is to make a Scheme value available to C code from within
Scheme.
@end deffn

@deffn {Scheme procedure} find-undefined-imported-bindings @returns{} vector
Returns a vector of all bindings imported into Scheme from C with
undefined values, @ie{} those created implicitly by lookups that have
not yet been assigned rather than those created explicitly by the
shared binding definers (@code{define-exported-binding}, @etc{}).
@end deffn

@subsection C shared binding interface

@deftypefn {C macro} s48_value S48_SHARED_BINDING_P (s48_value @var{obj})
@deftypefnx {C macro} s48_value S48_SHARED_BINDING_NAME (s48_value @var{shared_binding})
@deftypefnx {C macro} s48_value S48_SHARED_BINDING_IS_IMPORTP (s48_value @var{shared-binding})
@deftypefnx {C macro} s48_value S48_SHARED_BINDING_REF (s48_value @var{shared_binding})
@deftypefnx {C macro} void S48_SHARED_BINDING_SET (s48_value @var{shared_binding}, s48_value @var{value})
These macros are C counterparts to Scheme's @code{shared-binding?},
@code{shared-binding-name}, @code{shared-binding-is-import?},
@code{shared-binding-ref}, and @code{shared-binding-set!},
respectively.
@end deftypefn

@deftypefn {C macro} @i{statement} S48_SHARED_BINDING_CHECK (s48_value @var{binding})
Signals an exception if and only if @var{binding}'s value is
Scheme48's `unspecific' value.

@strong{Huh?:} Undefined shared bindings are not initialized with the
`unspecific' value, but rather with an entirely different special
token referred to internally as `undefined,' used in circumstances
such as this --- yet @code{S48_SHARED_BINDING_CHECK}, as defined in
@file{scheme48.h}, definitely checks whether @var{binding}'s value is
the `unspecific' value.
@end deftypefn

@cindex importing bindings into C from Scheme
@deftypefn {C function} s48_value s48_get_imported_binding (char *@var{name})
Returns the shared binding defined in Scheme for @var{name}, creating
it if necessary.
@end deftypefn

@cindex exporting bindings from C to Scheme
@deftypefn {C function} void s48_define_exported_binding (char *@var{name}, s48_value @var{value})
Defines a shared binding named @var{name} with the value @var{value}
that can be accessed from Scheme.
@end deftypefn

@cindex exporting C functions to Scheme
@deftypefn {C macro} void S48_EXPORT_FUNCTION (@var{fn})
This is a convenience for the common case of exporting a C function to
Scheme.  This expands into

@example
s48_define_exported_binding("@var{fn}",
                            s48_enter_pointer(@var{fn}))@end example

@noindent
which boxes the function into a Scheme48 byte vector and then exports
it as a shared binding.  Note that @code{s48_enter_pointer} allocates
space in the Scheme heap and may trigger a garbage collection;
@pxref{Interacting with the Scheme heap in C}.
@end deftypefn
